package org.example.handler;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import org.example.protocol.Packet;
import org.example.protocol.RpcRequest;
import org.example.protocol.RpcResponse;
import org.example.serializer.JSONSerializer;
import org.example.serializer.Serializer;

import java.util.HashMap;
import java.util.List;

@ChannelHandler.Sharable
public class PacketHandler extends MessageToMessageCodec<ByteBuf, Packet> {

    Serializer serializer = new JSONSerializer();

    private static HashMap<Byte, Class<? extends Packet>> packetMap;

    static {
        packetMap = new HashMap<>();
        packetMap.put((byte) 1, RpcRequest.class);
        packetMap.put((byte) 2, RpcResponse.class);
    }

    @Override
    protected void encode(ChannelHandlerContext ctx, Packet msg, List<Object> out) throws Exception {
        // 获取到一个缓冲区
        ByteBuf buffer = ctx.channel().alloc().buffer();

        // 序列化数据
        byte[] bytes = serializer.serialize(msg);

        // 写入消息类型
        buffer.writeByte(msg.getCommand());

        // 写入数据长度
        buffer.writeInt(bytes.length);

        // 写入数据
        buffer.writeBytes(bytes);

        // 添加到输出队列
        out.add(buffer);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {

        // 读取消息类型，并根据消息类型获取到对应的类
        byte command = msg.readByte();
        Class<? extends Packet> packet = getRequestType(command);

        // 创建一个字节数组，长度为数据长度
        byte[] bytes = new byte[msg.readInt()];

        // 读取序列化的数据
        msg.readBytes(bytes);

        // 将反序列化后的数据写到输出队列
        out.add(serializer.deserialize(packet, bytes));
    }

    /**
     * 根据command获取packet类型
     * @param command
     * @return
     */
    private Class<? extends Packet> getRequestType(byte command) {
        return packetMap.get(command);
    }
}
